Introduction

The ELF header is a data structure which sits at the beginning of every ELF file and describes its layout. It starts with 16 identification bytes that contain the ELF magic bytes. The following structs are defined in <elf.h>:

#define EI_NIDENT 16

typedef struct {
        unsigned char   e_ident[EI_NIDENT];
        Elf32_Half      e_type;
        Elf32_Half      e_machine;
        Elf32_Word      e_version;
        Elf32_Addr      e_entry;
        Elf32_Off       e_phoff;
        Elf32_Off       e_shoff;
        Elf32_Word      e_flags;
        Elf32_Half      e_ehsize;
        Elf32_Half      e_phentsize;
        Elf32_Half      e_phnum;
        Elf32_Half      e_shentsize;
        Elf32_Half      e_shnum;
        Elf32_Half      e_shstrndx;
} Elf32_Ehdr;

typedef struct {
        unsigned char   e_ident[EI_NIDENT];
        Elf64_Half      e_type;
        Elf64_Half      e_machine;
        Elf64_Word      e_version;
        Elf64_Addr      e_entry;
        Elf64_Off       e_phoff;
        Elf64_Off       e_shoff;
        Elf64_Word      e_flags;
        Elf64_Half      e_ehsize;
        Elf64_Half      e_phentsize;
        Elf64_Half      e_phnum;
        Elf64_Half      e_shentsize;
        Elf64_Half      e_shnum;
        Elf64_Half      e_shstrndx;
} Elf64_Ehdr;

  • e_ident - the initial magic bytes which denote an ELF file.
  • e_type - the type of the object file.
NameValueMeaning
ET_NONE0Unknown
ET_REL1Relocatable file
ET_EXEC2Executable file
ET_DYN3Shared object file
ET_CORE4Core file
ET_LOOS0xfe00Operating system-specific
ET_HIOS0xfeffOperating system-specific
ET_LOPROC0xff00Processor-specific
ET_HIPROC0xffffProcessor-specific
  • e_machine - specifies the required architecture. Values not labeled in the table are reserved for future machine names.
NameValueMeaning
EM_NONE0No machine
EM_M321AT&T WE 32100
EM_SPARC2SPARC
EM_3863Intel 80386
EM_68K4Motorola 68000
EM_88K5Motorola 88000
reserved6Reserved for future use (was EM_486)
EM_8607Intel 80860
EM_MIPS8MIPS I Architecture
EM_S3709IBM System/370 Processor
EM_MIPS_RS3_LE10MIPS RS3000 Little-endian
reserved11-14Reserved for future use
EM_PARISC15Hewlett-Packard PA-RISC
reserved16Reserved for future use
EM_VPP50017Fujitsu VPP500
EM_SPARC32PLUS18Enhanced instruction set SPARC
EM_96019Intel 80960
EM_PPC20PowerPC
EM_PPC642164-bit PowerPC
EM_S39022IBM System/390 Processor
reserved23-35Reserved for future use
EM_V80036NEC V800
EM_FR2037Fujitsu FR20
EM_RH3238TRW RH-32
EM_RCE39Motorola RCE
EM_ARM40Advanced RISC Machines ARM
EM_ALPHA41Digital Alpha
EM_SH42Hitachi SH
EM_SPARCV943SPARC Version 9
EM_TRICORE44Siemens TriCore embedded processor
EM_ARC45Argonaut RISC Core, Argonaut Technologies Inc.
EM_H8_30046Hitachi H8/300
EM_H8_300H47Hitachi H8/300H
EM_H8S48Hitachi H8S
EM_H8_50049Hitachi H8/500
EM_IA_6450Intel IA-64 processor architecture
EM_MIPS_X51Stanford MIPS-X
EM_COLDFIRE52Motorola ColdFire
EM_68HC1253Motorola M68HC12
EM_MMA54Fujitsu MMA Multimedia Accelerator
EM_PCP55Siemens PCP
EM_NCPU56Sony nCPU embedded RISC processor
EM_NDR157Denso NDR1 microprocessor
EM_STARCORE58Motorola Star*Core processor
EM_ME1659Toyota ME16 processor
EM_ST10060STMicroelectronics ST100 processor
EM_TINYJ61Advanced Logic Corp. TinyJ embedded processor family
EM_X86_6462AMD x86-64 architecture
EM_PDSP63Sony DSP Processor
EM_PDP1064Digital Equipment Corp. PDP-10
EM_PDP1165Digital Equipment Corp. PDP-11
EM_FX6666Siemens FX66 microcontroller
EM_ST9PLUS67STMicroelectronics ST9+ 8/16 bit microcontroller
EM_ST768STMicroelectronics ST7 8-bit microcontroller
EM_68HC1669Motorola MC68HC16 Microcontroller
EM_68HC1170Motorola MC68HC11 Microcontroller
EM_68HC0871Motorola MC68HC08 Microcontroller
EM_68HC0572Motorola MC68HC05 Microcontroller
EM_SVX73Silicon Graphics SVx
EM_ST1974STMicroelectronics ST19 8-bit microcontroller
EM_VAX75Digital VAX
EM_CRIS76Axis Communications 32-bit embedded processor
EM_JAVELIN77Infineon Technologies 32-bit embedded processor
EM_FIREPATH78Element 14 64-bit DSP Processor
EM_ZSP79LSI Logic 16-bit DSP Processor
EM_MMIX80Donald Knuth's educational 64-bit processor
EM_HUANY81Harvard University machine-independent object files
EM_PRISM82SiTera Prism
EM_AVR83Atmel AVR 8-bit microcontroller
EM_FR3084Fujitsu FR30
EM_D10V85Mitsubishi D10V
EM_D30V86Mitsubishi D30V
EM_V85087NEC v850
EM_M32R88Mitsubishi M32R
EM_MN1030089Matsushita MN10300
EM_MN1020090Matsushita MN10200
EM_PJ91picoJava
EM_OPENRISC92OpenRISC 32-bit embedded processor
EM_ARC_A593ARC Cores Tangent-A5
EM_XTENSA94Tensilica Xtensa Architecture
EM_VIDEOCORE95Alphamosaic VideoCore processor
EM_TMM_GPP96Thompson Multimedia General Purpose Processor
EM_NS32K97National Semiconductor 32000 series
EM_TPC98Tenor Network TPC processor
EM_SNP1K99Trebia SNP 1000 processor
EM_ST200100STMicroelectronics (www.st.com) ST200 microcontroller
  • e_version - specifies the ELF version.
NameValueMeaning
EV_NONE0Invalid version
EV_CURRENT1Current version
  • e_entry - the virtual address of the entry point. If there is no entry point, this member is 0.
  • e_phoff - the offset (in bytes) from the beginning of the ELF header for the Program Header Table. If the file does not contain such a table, this member is 0.
  • e_shoff - the offset (in bytes) from the beginning of the ELF header for the Section Header Table. If the file does not contain such a table, this member is 0.
  • e_flags - processor-specific flags which take values of the form EF_flag_name.
  • e_ehsize - the size of the ELF header in bytes.
  • e_phentsize - the size of an entry in the Program Header Table. All entries are equally-sized.
  • e_phnum - the number of entries in the Program Header Table.
  • e_shentsize - the size of an entry in the Section Header Table. All entries are equally-sized.
  • e_shnum - the number of entries in the Section Header Table. If the number of sections is greater than or equal to SHN_LORESERVE (0xff00), this member is 0 and the actual number of entries in the Section Header Table is contained in the sh_size field of the first section header (at index 0). Otherwise, the sh_size member of the initial entry contains 0.
  • e_shstrndx - the Section Header Table index of the entry which is associated with the section name string table. If there is no such table, this holds SHN_UNDEF. If this index is greater than or equal to SHN_LORESERVE (0xff00), this member contains SHN_XINDEX (0xffff) and the actual index of the section name string table section is stored in the sh_link field of the first section header (at index 0). Otherwise, the sh_link member of the initial entry contains 0.

ELF Identification

Since ELF supports multiple types of processors, data encodings and machines, the first 16 bytes provide information as to how to interpret the file, regardless of the rest of its contents. These are the indices and meaning of each identification byte (e_ident):

NameIndexPurpose
EI_MAG00File identification
EI_MAG11File identification
EI_MAG22File identification
EI_MAG33File identification
EI_CLASS4File class
EI_DATA5Data encoding
EI_VERSION6File version
EI_OSABI7Operating system/ABI identification
EI_ABIVERSION8ABI version
EI_PAD9Start of padding bytes
EI_NIDENT16Size of e_ident[]

The first 4 bytes contain the magic bytes which identify an ELF file and always have the same values:

NameValuePosition
ELFMAG00x7fe_ident[EI_MAG0]
ELFMAG1'E'e_ident[EI_MAG1]
ELFFMAG2'L'e_ident[EI_MAG2]
ELFFMAG3'F'e_ident[EI_MAG3]

Next is the EI_CLASS byte which describes the file's class - whether it is a 32-bit or 64-bit file.

NameValueMeaning
ELFCLASSNONE0Invalid class
ELFCLASS32132-bit
ELFCLASS64264-bit

EI_DATA specifies the encoding of the data structures in the ELF file.

NameValueMeaning
ELFDATANONE0Invalid data encoding
ELFDATA2LSB12's complement, little-endian
ELFDATA2MSB22's complement, big-endian

EI_VERSION contains the ELF header version and must be set to EV_CURRENT.

EI_OSABI specifies OS- or ABI-specific extensions used by the file. Certain fields in other ELF structures contain values with OS- or ABI-specific meaning and their interpretation is determined by this byte. This byte should be set to 0 if no such extensions are used. The meaning of values between 64 and 255 is determined by the e_machine member of the ELF header. Furthermore, ABIs may define their own meanings for this byte, but otherwise, it should be interpreted in the following way:

NameValueMeaning
ELFOSABI_NONE0No extensions
ELFOSABI_HPUX1Hewlett-Packard HP-UX
ELFOSABI_NETBSD2NetBSD
ELFOSABI_LINUX3Linux
ELFOSABI_SOLARIS6Sun Solaris
ELFOSABI_AIX7AIX
ELFOSABI_IRIX8IRIX
ELFOSABI_FREEBSD9FreeBSD
ELFOSABI_TRU6410Compaq TRU64 UNIX
ELFOSABI_MODESTO11Novell Modesto
ELFOSABI_OPENBSD12Open BSD
ELFOSABI_OPENVMS13Open VMS
ELFOSABI_NSK14Hewlett-Packard Non-Stop Kernel
64-255Architecture-specific value range

EI_ABIVERSION identifies the target ABI version and is used to distinguish between incompatible ABI versions. The byte's interpretation depends on the ABI specified by EI_OSABI. If it is unspecified, EI_ABIVERSION should contain 0.

EI_PAD - demarcates the beginning of the unused bytes in e_ident, which are reserved and set to 0. The value of this byte may change as meanings are assigned to these unused bytes.

You can view the ELF header of an ELF binary by using readelf with the -h option: